<template>
  <div v-if="!loading">

    <div style="margin-bottom: 20px;">

      <el-date-picker
          v-model="queryParams.startTime"
          type="datetime"
          placeholder="开始时间"
          style="margin-right: 10px;"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
      />
      <el-date-picker
          v-model="queryParams.endTime"
          type="datetime"
          placeholder="结束时间"
          style="margin-right: 10px;"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
      />
      <el-button @click="handleQuery">加载数据</el-button>
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['device:deviceInfo:export']"
        >导出</el-button>
    </div>

    <div v-if="uniqueCrackData.length!==0 || crackQingXie.length!==0 || crackData.length!==0 || fencenetData.length!==0 || geoData.length!==0 || weatherData.length!==0 || soilData.length!==0 " v-loading="loading">
    <!-- 裂缝变化图 -->
    <div v-if="uniqueCrackData.length" id="crackChangeChart" style="height: 400px; width: 100%;"></div>

    <!-- 裂缝倾角图 -->
    <div v-if="crackData.length || crackQingXie.length" id="tiltAnglesChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 裂缝加速度图 -->
    <div v-if="crackData.length || crackQingXie.length" id="accelerationChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 护栏网倾角图 -->
    <div v-if="fencenetData.length" id="fencenetTiltAnglesChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 护栏网加速度图 -->
    <div v-if="fencenetData.length" id="fencenetAccelerationChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

      <!-- 声压图 -->
    <div v-if="geoData.length" id="soundPressureChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 频率图 -->
    <div v-if="geoData.length" id="frequencyChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 降雨图 -->
    <div v-if="weatherData.length" id="rainfallChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 温度 -->
    <div v-if="weatherData.length" id="temperatureChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

      <!-- 土壤温度 -->
    <div v-if="soilData.length" id="soilTemperatureChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 土壤含水率 -->
    <div v-if="soilData.length" id="soilMoistureRatioChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

    <!-- 气压 -->
    <div v-if="weatherData.length" id="pressureChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

      <!-- 风速 -->
    <div v-if="weatherData.length" id="windChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

      <!-- 风向 -->
      <div v-if="weatherData.length" id="windDirectionChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>

      <!-- 湿度 -->
    <div v-if="weatherData.length" id="humidityChart" style="height: 400px; width: 100%; margin-top: 150px;"></div>
    </div>
    <div v-else class="no-data">
      无数据
    </div>

  </div>
</template>

<script setup>
import {listCrack, listQ} from '@/api/slope/data/crack.js';  // 引入API
import {listGeoacoustic} from '@/api/slope/data/geoacoustic.js';
import {listSoil} from '@/api/slope/data/soil.js';
import {listWeather} from '@/api/slope/data/weather.js';
import {listFencenet} from "@/api/slope/data/fencenet.js";
import dayjs from 'dayjs';
import * as echarts from 'echarts';
import * as XLSX from 'xlsx';
import { saveAs } from "file-saver";
import axios from "axios";
import { getToken } from "@/utils/auth";
import {uploadDataDownload} from "@/api/slope/device/dataDownload/dataDownload.js";
const commonToolbox = {
  feature: {
    saveAsImage: {},
    dataZoom: {},
    restore: {},
    dataView: {},
    magicType: {
      type: ['line', 'bar']
    }
  },
  right: '5%',
  top: '10'
};

// 公共X轴标签配置（自动间隔、旋转、格式化）
const commonAxisLabel = {
  formatter: value => value.slice(6, 10),
  rotate: 45,
  interval: 'auto'
};

const commonDataZoom = [
  {
    type: 'slider',
    show: true,
    xAxisIndex: 0,
    start: 80,   // 显示最左边
    end: 100,    // 显示前 20% 的数据
    filterMode: 'filter'
  },
  {
    type: 'inside',
    xAxisIndex: 0,
    start:80,
    end: 100,
    filterMode: 'filter'
  }
];



const loading = ref(true)
const crackData = ref([])
const crackQingXie = ref([])
const geoData = ref([])
const soilData = ref([])
const weatherData = ref([])
const fencenetData = ref([])
const uniqueCrackData = ref([])

// 接收 props
const props = defineProps({
  deviceSn: {
    type: String,
    required: true
  }
});

const data = reactive({
  queryParams: {
    pageSize: 100000000,
    deviceSn: props.deviceSn,
    startTime: dayjs().subtract(30, 'day').format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
  }
});

const { queryParams } = toRefs(data);

onMounted(() => {
  getList();
});

function handleQuery(){
  getList();
}

async function getList() {
  loading.value = true;
  try {
    const [crackRes, crackQingXieRes,geoRes, soilRes, weatherRes, fRes] = await Promise.all([
      listCrack(queryParams.value),
      listQ(queryParams.value),
      listGeoacoustic(queryParams.value),
      listSoil(queryParams.value),
      listWeather(queryParams.value),
      listFencenet(queryParams.value)
    ]);
    crackData.value = crackRes.rows.reverse();
    crackQingXie.value = crackQingXieRes.rows.reverse();
    geoData.value = geoRes.rows.reverse();
    soilData.value = soilRes.rows.reverse();
    weatherData.value = weatherRes.rows.reverse();
    fencenetData.value = fRes.rows.reverse();
    uniqueCrackData.value = (crackRes?.rows?.flatMap(item => item.crackChange || []) || []).reverse();

    // 等待 DOM 渲染完毕后，再设置 loading 为 false
    await nextTick();
    loading.value = false;
    // 再等待一次 DOM 更新后再初始化图表
    await nextTick();
    initChart();

  } catch (error) {
    console.error(error);
  } finally {
    loading.value = false;
  }
}

function initChart(){
  if(crackData.value.length > 0){
    initCrackChangeChart(crackData);
    initTiltAnglesChart(crackData);
    initAccelerationChart(crackData);
  }
  if(crackQingXie.value.length>0){
    initTiltAnglesChart(crackQingXie);
    initAccelerationChart(crackQingXie);
  }
  if(geoData.value.length > 0){
    initSoundPressureChart();
    initFrequencyChart();
  }
  if(weatherData.value.length > 0){
    initRainfallChart();
    initTemperatureChart();
    initPressureChart();
    initWindChart();
    initWindDirectionChart();
    initHumidityChart();
  }
  if(soilData.value.length > 0){
    initSoilTemperatureChart();
    initSoilMoistureRatioChart();
  }
  if(fencenetData.value.length > 0){
    initFencenetTiltAnglesChart();
    initFencenetAccelerationChart();
  }
}

function initCrackChangeChart(crackData) {
  const chartDom = document.getElementById('crackChangeChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = crackData.value.map(item => item.updateTime);
  const values = crackData.value.map(item => item.crackChange);

  const option = {
    title: { text: '裂缝变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: 'mm' },
    series: [{
      name: '裂缝变化',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initTiltAnglesChart(crackData) {
  const chartDom = document.getElementById('tiltAnglesChart');
  if (!chartDom) {
    return;
  }

  const myChart = echarts.init(chartDom);

  // 数据准备
  const times = crackData.value.map(item => item.updateTime);
  const x = crackData.value.map(item => item.xtiltAngle);
  const y = crackData.value.map(item => item.ytiltAngle);
  const z = crackData.value.map(item => item.ztiltAngle);
  const xy = crackData.value.map(item => item.xyTiltAngle);

  const option = {
    title: { text: '倾角变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['X倾角', 'Y倾角', 'Z倾角', 'XY合倾角']
    },
    toolbox: commonToolbox, // 使用公共配置
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: '倾角（度）'
    },
    series: [
      {
        name: 'X倾角',
        type: 'line',
        data: x,
        smooth: true
      },
      {
        name: 'Y倾角',
        type: 'line',
        data: y,
        smooth: true
      },
      {
        name: 'Z倾角',
        type: 'line',
        data: z,
        smooth: true
      },
      {
        name: 'XY合倾角',
        type: 'line',
        data: xy,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom // 使用公共配置
  };

  myChart.setOption(option);
}

function initAccelerationChart(crackData) {
  const chartDom = document.getElementById('accelerationChart');
  if (!chartDom) {
    return;
  }

  const myChart = echarts.init(chartDom);

  // 数据准备
  const times = crackData.value.map(item => item.updateTime);
  const x = crackData.value.map(item => item.xacceleration);
  const y = crackData.value.map(item => item.yacceleration);
  const z = crackData.value.map(item => item.zacceleration);

  const option = {
    title: { text: '加速度变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['X方向加速度', 'Y方向加速度', 'Z方向加速度']
    },
    toolbox: commonToolbox, // 使用公共配置
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: '加速度（mg）',
      axisLabel: {
        formatter: function (value) {
          return value.toFixed(4); // 显示小数点后 4 位，不用科学计数法
        }
      }
    },
    series: [
      {
        name: 'X方向加速度',
        type: 'line',
        data: x,
        smooth: true
      },
      {
        name: 'Y方向加速度',
        type: 'line',
        data: y,
        smooth: true
      },
      {
        name: 'Z方向加速度',
        type: 'line',
        data: z,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom // 使用公共配置
  };

  myChart.setOption(option);
}

function initSoundPressureChart() {
  const chartDom = document.getElementById('soundPressureChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = geoData.value.map(item => item.updateTime);
  const original = geoData.value.map(item => item.originalSoundPressure);
  const effective = geoData.value.map(item => item.effectiveSoundPressure);

  const option = {
    title: { text: '地声变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    legend: {
      top: '10%',
      left: 'center',
      data: ['地声原始声压', '地声有效声压']
    },
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: 'Pa'
    },
    series: [
      {
        name: '地声原始声压',
        type: 'line',
        data: original,
        smooth: true
      },
      {
        name: '地声有效声压',
        type: 'line',
        data: effective,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initFrequencyChart() {
  const chartDom = document.getElementById('frequencyChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = geoData.value.map(item => item.updateTime);
  const values = geoData.value.map(item => item.frequencySignal);

  const option = {
    title: { text: '地声频率变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: 'Hz' },
    series: [{
      name: '地声频率',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initRainfallChart() {
  const chartDom = document.getElementById('rainfallChart');
  if (!chartDom) {
    return;
  }
  const myChart = echarts.init(chartDom);

  // 数据准备
  const times = weatherData.value.map(item => item.updateTime);
  const c = weatherData.value.map(item => item.cumulativeRainfall);
  const d = weatherData.value.map(item => item.dailyRainfall);
  const h = weatherData.value.map(item => item.hourlyRainfall);
  const m = weatherData.value.map(item => item.minRainfall);

  const option = {
    title: { text: '降雨量变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['累计降雨量', '日降雨量', '小时降雨量','分钟降雨量']
    },
    toolbox: commonToolbox, // 使用公共配置
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: '降雨量（mm）'
    },
    series: [
      {
        name: '累计降雨量',
        type: 'line',
        data: c,
        smooth: true
      },
      {
        name: '日降雨量',
        type: 'line',
        data: d,
        smooth: true
      },
      {
        name: '小时降雨量',
        type: 'line',
        data: h,
        smooth: true
      },
      {
        name: '分钟降雨量',
        type: 'line',
        data: m,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom // 使用公共配置
  };

  myChart.setOption(option);
}

function initTemperatureChart() {
  const chartDom = document.getElementById('temperatureChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = weatherData.value.map(item => item.updateTime);
  const values = weatherData.value.map(item => item.temperature);

  const option = {
    title: { text: '气温变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: '℃' },
    series: [{
      name: '气温变化',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };

  myChart.setOption(option);
}

function initSoilTemperatureChart() {
  const chartDom = document.getElementById('soilTemperatureChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = soilData.value.map(item => item.updateTime);
  const s0 = soilData.value.map(item => item.soilTemperature0);
  const s1 = soilData.value.map(item => item.soilTemperature1);
  const s2 = soilData.value.map(item => item.soilTemperature2);
  const s3 = soilData.value.map(item => item.soilTemperature3);
  const s4 = soilData.value.map(item => item.soilTemperature4);

  const option = {
    title: { text: '土壤分层温度折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['第一层', '第二层', '第三层', '第四层','第五层']
    },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: '℃' },
    series: [
      {
        name: '第一层',
        type: 'line',
        data: s0,
        smooth: true
      },
      {
        name: '第二层',
        type: 'line',
        data: s1,
        smooth: true
      },
      {
        name: '第三层',
        type: 'line',
        data: s2,
        smooth: true
      },
      {
        name: '第四层',
        type: 'line',
        data: s3,
        smooth: true
      },
      {
        name: '第五层',
        type: 'line',
        data: s4,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };

  myChart.setOption(option);
}

function initSoilMoistureRatioChart() {
  const chartDom = document.getElementById('soilMoistureRatioChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = soilData.value.map(item => item.updateTime);
  const s0 = soilData.value.map(item => item.soilMoistureRatio0);
  const s1 = soilData.value.map(item => item.soilMoistureRatio1);
  const s2 = soilData.value.map(item => item.soilMoistureRatio2);
  const s3 = soilData.value.map(item => item.soilMoistureRatio3);
  const s4 = soilData.value.map(item => item.soilMoistureRatio4);

  const option = {
    title: { text: '土壤分层湿度折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['第一层', '第二层', '第三层', '第四层','第五层']
    },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: '%' },
    series: [
      {
        name: '第一层',
        type: 'line',
        data: s0,
        smooth: true
      },
      {
        name: '第二层',
        type: 'line',
        data: s1,
        smooth: true
      },
      {
        name: '第三层',
        type: 'line',
        data: s2,
        smooth: true
      },
      {
        name: '第四层',
        type: 'line',
        data: s3,
        smooth: true
      },
      {
        name: '第五层',
        type: 'line',
        data: s4,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };

  myChart.setOption(option);
}

function initPressureChart() {
  const chartDom = document.getElementById('pressureChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = weatherData.value.map(item => item.updateTime);
  const values = weatherData.value.map(item => item.pressure);

  const option = {
    title: { text: '气压变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: 'hPa' },
    series: [{
      name: '气压',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initWindChart() {
  const chartDom = document.getElementById('windChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = weatherData.value.map(item => item.updateTime);
  const values = weatherData.value.map(item => item.windSpeed);

  const option = {
    title: { text: '风速变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: 'm/s' },
    series: [{
      name: '风速',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initWindDirectionChart() {
  const chartDom = document.getElementById('windDirectionChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = weatherData.value.map(item => item.updateTime);
  const values = weatherData.value.map(item => item.windDirection);

  const option = {
    title: { text: '风向变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: '°' },
    series: [{
      name: '风向',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initHumidityChart() {
  const chartDom = document.getElementById('humidityChart');
  if (!chartDom){
    return;
  }
  const myChart = echarts.init(chartDom);

  // 格式化数据：横轴时间，纵轴裂缝变化值
  const times = weatherData.value.map(item => item.updateTime);
  const values = weatherData.value.map(item => item.humidity);

  const option = {
    title: { text: '空气湿度变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    toolbox: commonToolbox,
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: { type: 'value', name: '%RH' },
    series: [{
      name: '空气湿度',
      type: 'line',
      data: values,
      smooth: true,
      lineStyle: { width: 2 },
      itemStyle: { color: '#5470C6' }
    }],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom
  };


  myChart.setOption(option);
}

function initFencenetTiltAnglesChart() {
  const chartDom = document.getElementById('fencenetTiltAnglesChart');
  if (!chartDom) {
    return;
  }

  const myChart = echarts.init(chartDom);

  // 数据准备
  const times = fencenetData.value.map(item => item.updateTime);
  const x = fencenetData.value.map(item => item.xtiltAngle);
  const y = fencenetData.value.map(item => item.ytiltAngle);
  const z = fencenetData.value.map(item => item.ztiltAngle);

  const option = {
    title: { text: '护栏网倾角变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['X倾角', 'Y倾角', 'Z倾角']
    },
    toolbox: commonToolbox, // 使用公共配置
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: '倾角（度）'
    },
    series: [
      {
        name: 'X倾角',
        type: 'line',
        data: x,
        smooth: true
      },
      {
        name: 'Y倾角',
        type: 'line',
        data: y,
        smooth: true
      },
      {
        name: 'Z倾角',
        type: 'line',
        data: z,
        smooth: true
      },
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom // 使用公共配置
  };

  myChart.setOption(option);
}

function initFencenetAccelerationChart() {
  const chartDom = document.getElementById('fencenetAccelerationChart');
  if (!chartDom) {
    return;
  }

  const myChart = echarts.init(chartDom);

  // 数据准备
  const times = fencenetData.value.map(item => item.updateTime);
  const x = fencenetData.value.map(item => item.xacceleration);
  const y = fencenetData.value.map(item => item.yacceleration);
  const z = fencenetData.value.map(item => item.zacceleration);

  const option = {
    title: { text: '护栏网加速度变化折线图', left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      top: '10%',
      left: 'center',
      data: ['X方向加速度', 'Y方向加速度', 'Z方向加速度']
    },
    toolbox: commonToolbox, // 使用公共配置
    xAxis: {
      type: 'category',
      data: times,
      axisLabel: commonAxisLabel
    },
    yAxis: {
      type: 'value',
      name: '加速度（mg）'
    },
    series: [
      {
        name: 'X方向加速度',
        type: 'line',
        data: x,
        smooth: true
      },
      {
        name: 'Y方向加速度',
        type: 'line',
        data: y,
        smooth: true
      },
      {
        name: 'Z方向加速度',
        type: 'line',
        data: z,
        smooth: true
      }
    ],
    grid: { left: '10%', right: '10%', bottom: '25%' },
    dataZoom: commonDataZoom // 使用公共配置
  };

  myChart.setOption(option);
}

async function handleExport() {
  try {
    const wb = XLSX.utils.book_new();
    const sn = props.deviceSn || "未知设备";
    let dataType = ""
    // ----------------- 裂缝数据 -----------------
    if (crackData.value.length) {
      dataType = "裂缝数据"
      const crackSheet = XLSX.utils.json_to_sheet(
          crackData.value.map(item => ({
            "时间": item.updateTime,
            "裂缝变化 (mm)": item.crackChange,
            "X倾角 (°)": item.xtiltAngle,
            "Y倾角 (°)": item.ytiltAngle,
            "Z倾角 (°)": item.ztiltAngle,
            "XY合倾角 (°)": item.xyTiltAngle,
            "X加速度 (m/s²)": item.xacceleration,
            "Y加速度 (m/s²)": item.yacceleration,
            "Z加速度 (m/s²)": item.zacceleration
          }))
      );
      XLSX.utils.book_append_sheet(wb, crackSheet, `${sn}_裂缝数据`);
    }

    // ----------------- 裂缝倾斜数据 -----------------
    if (crackQingXie.value.length) {
      dataType = "裂缝倾斜数据"
      const tiltSheet = XLSX.utils.json_to_sheet(
          crackQingXie.value.map(item => ({
            "时间": item.updateTime,
            "X倾角 (°)": item.xtiltAngle,
            "Y倾角 (°)": item.ytiltAngle,
            "Z倾角 (°)": item.ztiltAngle,
            "XY合倾角 (°)": item.xyTiltAngle,
            "X加速度 (m/s²)": item.xacceleration,
            "Y加速度 (m/s²)": item.yacceleration,
            "Z加速度 (m/s²)": item.zacceleration
          }))
      );
      XLSX.utils.book_append_sheet(wb, tiltSheet, `${sn}_裂缝倾斜数据`);
    }

    // ----------------- 护栏网数据 -----------------
    if (fencenetData.value.length) {
      dataType = "护栏网数据"
      const fSheet = XLSX.utils.json_to_sheet(
          fencenetData.value.map(item => ({
            "时间": item.updateTime,
            "X倾角 (°)": item.xtiltAngle,
            "Y倾角 (°)": item.ytiltAngle,
            "Z倾角 (°)": item.ztiltAngle,
            "X加速度 (m/s²)": item.xacceleration,
            "Y加速度 (m/s²)": item.yacceleration,
            "Z加速度 (m/s²)": item.zacceleration
          }))
      );
      XLSX.utils.book_append_sheet(wb, fSheet, `${sn}_护栏网数据`);
    }

    // ----------------- 地声数据 -----------------
    if (geoData.value.length) {
      dataType = "地声数据"
      const geoSheet = XLSX.utils.json_to_sheet(
          geoData.value.map(item => ({
            "时间": item.updateTime,
            "原始声压 (Pa)": item.originalSoundPressure,
            "有效声压 (Pa)": item.effectiveSoundPressure,
            "频率 (Hz)": item.frequencySignal
          }))
      );
      XLSX.utils.book_append_sheet(wb, geoSheet, `${sn}_地声数据`);
    }

    // ----------------- 土壤数据 -----------------
    if (soilData.value.length) {
      dataType = "土壤数据"
      const soilSheet = XLSX.utils.json_to_sheet(
          soilData.value.map(item => ({
            "时间": item.updateTime,
            "土壤温度0 (℃)": item.soilTemperature0,
            "土壤温度1 (℃)": item.soilTemperature1,
            "土壤温度2 (℃)": item.soilTemperature2,
            "土壤温度3 (℃)": item.soilTemperature3,
            "土壤温度4 (℃)": item.soilTemperature4,
            "土壤含水率0 (%)": item.soilMoistureRatio0,
            "土壤含水率1 (%)": item.soilMoistureRatio1,
            "土壤含水率2 (%)": item.soilMoistureRatio2,
            "土壤含水率3 (%)": item.soilMoistureRatio3,
            "土壤含水率4 (%)": item.soilMoistureRatio4
          }))
      );
      XLSX.utils.book_append_sheet(wb, soilSheet, `${sn}_土壤数据`);
    }

    // ----------------- 天气数据 -----------------
    if (weatherData.value.length) {
      dataType = "天气数据"
      const weatherSheet = XLSX.utils.json_to_sheet(
          weatherData.value.map(item => ({
            "时间": item.updateTime,
            "气温 (℃)": item.temperature,
            "累计降雨量 (mm)": item.cumulativeRainfall,
            "日降雨量 (mm)": item.dailyRainfall,
            "小时降雨量 (mm)": item.hourlyRainfall,
            "分钟降雨量 (mm)": item.minRainfall,
            "气压 (Pa)": item.pressure,
            "风速 (m/s)": item.windSpeed,
            "风向 (°)": item.windDirection,
            "湿度 (%)": item.humidity
          }))
      );
      XLSX.utils.book_append_sheet(wb, weatherSheet, `${sn}_天气数据`);
    }

    // ----------------- 生成 Blob -----------------
    const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });
    const blob = new Blob([wbout], { type: "application/octet-stream" });

    // ----------------- 下载本地 -----------------
    saveAs(blob, `${sn}_数据导出.xlsx`);

    // ----------------- 上传到后端 -----------------
    const formData = new FormData();
    formData.append("file", new File([blob], `${sn}_数据导出.xlsx`));
    formData.append("deviceSn", sn);
    formData.append("dataType", dataType);


    uploadDataDownload(formData).then(res => {
      if (res.code === 200) {
        console.log("上传成功", res);
      } else {
        console.error("上传失败", res.msg);
      }
    });

    if (res.data.code === 200) {
      console.log("上传成功", res.data);
    } else {
      console.error("上传失败", res.data.msg);
    }

  } catch (err) {
    console.error("导出或上传异常", err);
  }
}


</script>
<style>
.no-data {
  padding: 20px;
  margin: 20px auto;
  max-width: 300px;
  text-align: center;
  color: #999999;
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 18px;
  font-weight: 500;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
  user-select: none;
}
</style>